package cz.muni.fi.pa165.soccergamesarchive.businesslayer.services;

import cz.muni.fi.pa165.soccergamesarchive.businesslayer.dtos.GoalDTO;
import cz.muni.fi.pa165.soccergamesarchive.errorhandling.ErrorHandler;
import cz.muni.fi.pa165.soccergamesarchive.persistencelayer.daos.GoalDAO;
import cz.muni.fi.pa165.soccergamesarchive.persistencelayer.entities.Goal;
import cz.muni.fi.pa165.soccergamesarchive.validators.ValidatorTest;
import java.util.List;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;

import static cz.muni.fi.pa165.soccergamesarchive.errorhandling.ErrorHandler.createErrorMessage;
import static cz.muni.fi.pa165.soccergamesarchive.utils.EntityDTOTransformer.transform;
import static cz.muni.fi.pa165.soccergamesarchive.utils.EntityDTOTransformer.transformList;
import static cz.muni.fi.pa165.soccergamesarchive.validators.GoalValidator.validateGoal;

/**
 * goal service bean
 *
 * @author Tomas Plevko <tomasplevko@gmail.com>
 */
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@DeclareRoles("Archiver")
@Stateless
public class GoalServiceBean implements GoalServiceBeanLocal {

    @EJB
    private GoalDAO goalDao;

    public void setGoalDao(GoalDAO goalDao) {
        this.goalDao = goalDao;
    }

    @RolesAllowed("Archiver")
    @Override
    public GoalDTO addGoal(GoalDTO goalDto) throws RuntimeException {

        Goal goal = transform(goalDto, Goal.class);

        validateGoal(goal, ValidatorTest.NULL_TEST,
                ValidatorTest.CORRECT_RECORD_TEST);

        goalDao.addGoal(goal);
        return transform(goal, GoalDTO.class);
    }

    @RolesAllowed("Archiver")
    @Override
    public GoalDTO changeGoal(GoalDTO goalDto) throws RuntimeException {

        Goal goal = transform(goalDto, Goal.class);

        validateGoal(goal, ValidatorTest.FULL_TEST);

        return transform(goalDao.changeGoal(goal), GoalDTO.class);
    }

    @RolesAllowed("Archiver")
    @Override
    public void deleteGoal(GoalDTO goalDto) throws RuntimeException {

        Goal goal = transform(goalDto, Goal.class);

        validateGoal(goal, ValidatorTest.ID_TEST, ValidatorTest.NULL_TEST);

        goalDao.deleteGoal(goal);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public List<GoalDTO> getAllGoals() throws RuntimeException {

        return transformList(goalDao.getAllGoals(), GoalDTO.class);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public List<GoalDTO> getLimitedNumberOfGoals(int offset, int limit) throws
            RuntimeException {

        if (offset < 0 || limit <= 0) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), ErrorHandler.ILLEGAL_VALUE_ERROR));
        }

        return transformList(goalDao.getLimitedNumberOfGoals(offset, limit),
                GoalDTO.class);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    @Override
    public GoalDTO getGoalById(Long id) throws RuntimeException {

        if (id == null || id < 1) {
            throw new IllegalArgumentException(createErrorMessage(
                    this.getClass().getName(), ErrorHandler.ILLEGAL_VALUE_ERROR));
        }

        return transform(goalDao.getGoalById(id), GoalDTO.class);
    }

}
